package com.bloveoa.zkkd.controller;

import com.bloveoa.zkkd.annotation.ResponseBodyWrapper;
import com.bloveoa.zkkd.doman.LockedTokenModel;
import com.bloveoa.zkkd.doman.UserModel;
import com.bloveoa.zkkd.exception.CommonException;
import com.bloveoa.zkkd.service.LockedTokenService;
import com.bloveoa.zkkd.service.UserService;
import com.bloveoa.zkkd.util.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.web3j.crypto.WalletUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

@RestController
@RequestMapping("/user")
@ResponseBodyWrapper
@Slf4j
public class UserController {

    private final UserService userService;
    private final LockedTokenService lockedTokenService;

    public UserController(UserService userService, LockedTokenService lockedTokenService) {
        this.userService = userService;
        this.lockedTokenService = lockedTokenService;
    }

    @ApiOperation(value = "绑定盒子到用户")
    @ApiImplicitParams({ // 参数说明
            @ApiImplicitParam(name = "address", required = true, paramType = "query", value = "绑定的地址", dataType = "string"),
            @ApiImplicitParam(name = "mac", required = true, paramType = "query", value = "盒子的mac", dataType = "string"),
    })
    @GetMapping("/bingBoxToUser")
    public R<UserModel> bingBoxToUser(String address, String mac) {
        if (!WalletUtils.isValidAddress(address)) {
            throw new CommonException(R.Enum.ADDRESS_ERROR);
        }
        if (mac.length() != 12) {
            throw new CommonException(R.Enum.MAC_ERROR);
        }
        mac = StringUtils.getMacFromData(mac);
        if (userService.existsByMac(mac)) {
            throw new CommonException(R.Enum.USER_BIINDED);
        }
        log.error("000");
        //不存在就创建
        return RUtil.ok(userService.saveBoxUser(address, mac));
    }

    @ApiOperation(value = "通过地址查询用户信息")
    @ApiImplicitParams({ // 参数说明
            @ApiImplicitParam(name = "address", required = true, paramType = "query", value = "绑定的地址", dataType = "string"),
    })
    @GetMapping("/queryUser")
    public R<UserModel> queryUser(String address) {
        if (!WalletUtils.isValidAddress(address)) {
            throw new CommonException(R.Enum.ADDRESS_ERROR);
        }
        UserModel userModel = userService.queryByAddress(address);
        return RUtil.ok(userModel);
    }

    @ApiOperation(value = "通过地址查询用户信息")
    @ApiImplicitParams({ // 参数说明
            @ApiImplicitParam(name = "address", required = true, paramType = "query", value = "锁仓的地址", dataType = "string"),
            @ApiImplicitParam(name = "number", required = true, paramType = "query", value = "锁仓的token数量", dataType = "int"),
            @ApiImplicitParam(name = "longtime", required = true, paramType = "query", value = "锁仓的token时长", dataType = "int"),
    })
    @PostMapping("/lockeTokenNum")
    public R<UserModel> lockeTokenNum(String address, int number, int longtime) {
        if (!WalletUtils.isValidAddress(address)) {
            throw new CommonException(R.Enum.ADDRESS_ERROR);
        }
        UserModel userModel = userService.queryByAddress(address);
        if (userModel == null) {
            throw new CommonException(R.Enum.USER_NOT_FOUND);
        }
        if (number > userModel.getTokenNum()) {
            throw new CommonException(R.Enum.LOCKED_ERROR);
        }
        LockedTokenModel lockedTokenModel = new LockedTokenModel().setLockedLong(longtime).setLockedTokenNum(number).setLockedType(0).setUserId(String.valueOf(userModel.getId()));
        Date from = Date.from(LocalDateTime.now().plusDays(longtime  * 30).toLocalDate().atStartOfDay(ZoneId.systemDefault()).toInstant());
        lockedTokenModel.setLockEndTime(from);
        lockedTokenModel.setLockStartTime(new Date());
        lockedTokenService.insertLockedToken(lockedTokenModel);
        return RUtil.ok(userModel);
    }
}
